import math
import time
import event.event
import logo.Mlog
import taskPro.taskPro
import tool.arrHelp
import yolo
from dataTemp.prop import Prop
from dataTemp.user import Role, User
from match.font import get_plz
from process.player import Player
from tool.encounterTracker import EncounterTracker
from tool.rect import Rectangle
from tool.vector import Vector


class Copy:
    def __init__(self):
        self.six_in_leo_room: bool = False
        self.leo_condition = None
        self.user: User = User()
        # Role(4, "百花", 9)
        self.role: Role = Role(1, "鬼泣", 9)
        # 是否在城镇，默认是true
        self.is_at_town: bool =True
    
        self.player = Player()
        self.name: str = "布万家"
        # 房间是否通关了
        self.room_is_ok: bool = False
        #  是否通关了
        self.clearance: bool = False
        # 进入狮子头房间的条件是否触发了
        leo_condition: bool = False
        # 狮子头是否打过了
        self.leo_ok: bool = False
        # 当前是否在狮子头房间
        self.leo_room: bool = False
        # 当前是否在狮子头的前一个房间
        self.leo_pre_room: bool = False
        # 狮子头房间是否到达过
        self.boss_room: bool = False
        # local_enemy: [str] = []
        self.enemy = []
        self.stuff = []
        # 三角形路标
        self.guidepost = []
        self.exports = []
        self.ico = []
        # boss路标,终点引路标志
        self.end_guidepost: Prop = None
        self.first_room: bool = True
        # over_move_time: int = 0
        self.sm = None
        self.cut_times: EncounterTracker = EncounterTracker()
        self.rect: Rectangle = None
        self.props = None
        # 通关次数
        self.times: EncounterTracker = EncounterTracker()
        self.agan_fail_times: int = 0
        self.get_screens()
        self.is_through: bool = False
        # logo.Mlog.logger.debug(f"当前Copy=初始化")
        # self.user.roles = [Role(5, "阿修罗", 8), Role(4, "百花", 8), Role(3, "奶妈", 8),
        #                    Role(1, "鬼泣", 10)]

    def get_prop(self, stop_event):
        # yolo.get_prop(self.role.job)
        while not stop_event.is_set():
            if self.role is None or self.role.job == "":
                continue
            # logo.Mlog.logger.error("加入门柱")
            self.props = yolo.get_prop(self.role.job)

            # if self.props is None: continue
            # self.set_prop()
            # time.sleep(0.5)

    def check_times(self):
        for ic in self.ico:
            if ic.name == "通关" or ic.name == "金牌" or "返回城镇":
                self.times.add_enemy_encounter(1)
        self.role.set_times(self.times.count_01_pairs())

    # 这要单独开一个线程
    def set_prop(self):
        props = self.props
        if props is None: return
        # 把距离终点路标最近的房间门，加入移动路径
        if len(props[6]) > 0:
            self.exports = props[6]
            if len(self.exports) >= 6 and not self.leo_ok and not self.six_in_leo_room:
                self.six_in_leo_room = True
                self.leo_pre_room = True
                logo.Mlog.logger.error("6个门柱进入狮子头前一个房间状态")
            # if not self.room_is_ok:
            #     self.room_is_ok = True
            # logo.Mlog.logger.error("加入门柱")
        self.enemy = props[0]

        # self.boss_move_pots[em.name] = em.pot
        self.stuff = props[1]
        self.guidepost = props[2]
        self.ico = props[5]
        # 最终房间的路标只要出现一次，后面没有检测到，也不要消失
        if not (props[3] is None):
            filtered_list = [x for x in self.exports if
                             Vector.distance(x.getPot(),
                                             props[3].getPot()) <= props[3].getWH().y * 3]
            if len(filtered_list) <= 0: return
            self.end_guidepost = props[3]
        self.is_leo_pre_room()
        # return
        # self.check_times()
        # 最终房间的路标只要出现一次
        # self.end_guidepost_temp = props[3]
        # 角色只要检测到了一次，有时候没有检测到就不要赋值
        self.player.temp_pot = props[4]
        if not (self.player.temp_pot is None):
            self.player.position = self.player.temp_pot.getPot()
            if self.player.wh is None:
                self.player.wh = self.player.temp_pot.getWH()
            # logo.Mlog.logger.error(f"角色找到了 {self.player.position}")
        # # 条件满足后，下一个房间，如果没有敌人，说明走错了
        # if self.leo_condition and not (self.end_guidepost is None) or len(self.guidepost) > 0 or len(self.exports):
        #     self.leo_condition = False
        #     self.leo_pre_room = False
        # 检测到房间切换，直接先进入落单模式
        if props[7]:
            self.cut_times.add_enemy_encounter(1)
            logo.Mlog.logger.error("----------------进入切换房间状态---------------")
            self.player.yg.mouse_controller.clear_mouse()
            self.sm.transition_to("et")
            self.cut_room_reset()
            self.clearance = False
            self.first_room = False
            # time.sleep(1)
            # self.leo_pre_room = False
            # self.is_cut_room = True
            # time.sleep(1)
            if self.leo_pre_room and self.leo_condition:
                self.leo_pre_room = False
                self.leo_condition = False
            # 如果是通过6个门柱进入狮子头房间的，切换房间时直接取消
            if self.six_in_leo_room:
                self.six_in_leo_room = False
                self.leo_pre_room = False
                # logo.Mlog.logger.error("6个门柱进入切换房间关闭狮子头状态")
            return
        # 如果在狮子头房间就释放觉醒
        global szt_num
        szt_num = []
        for em in self.enemy:
            # 有可能在狮子头的前一个房间就会遇到狮子头
            if em.name == "狮子头" or em.name == "邪恶娃娃" or em.name == "光头娃娃" or em.name == "狮子头手上" or em.name == "狮子头手下":
                szt_num.append(em)
                # 记录狮子头移动过的坐标
            if em.name == "布万家Boss":
                self.times.add_enemy_encounter(0)
                # 记录狮子头移动过的坐标
                # self.boss_room = True
                # self.leo_pre_room = False
                # logo.Mlog.logger.debug(f"检测到在布万家Boss房间")
            # 如果是通过路标+门柱进入狮子头房间的，只有遇到敌人时才，开启狮子头前一个状态
            if em.name == "班图高战士" and self.leo_condition and not self.leo_ok and self.cut_times.count_01_pairs() > 3:
                self.leo_condition = False
                self.leo_pre_room = True
                logo.Mlog.logger.error(f"路标+门柱 进入狮子头前一个房间状态{self.cut_times.count_01_pairs()}")
        if len(szt_num) >= 4:
            self.leo_pre_room = False
            self.six_in_leo_room = False
            self.leo_room = True
            self.leo_ok = True
            for szt in szt_num:
                logo.Mlog.logger.error(f"检测到在狮子头房间={szt.name} ={szt_num}")
        szt_num = 0
        # # 提前进入
        # if self.leo_pre_room and not self.leo_ok:
        #     logo.Mlog.logger.warning(f"进入 狮子头 状态 {self.six_in_leo_room}")
        #     return
        # 是否通关
        boss_guidepost_list = [x for x in self.exports if x.name == "领主入口"]
        if len(boss_guidepost_list) > 1 and not self.leo_ok:
            self.leo_pre_room = True
            logo.Mlog.logger.error("领主入口 进入狮子头前一个房间状态")
            self.sm.transition_to("szt_pre")
            return

        global y
        # 只要没有如何通关的迹象，就加入敌人len(props[0]) <= 0 or
        if len(props[0]) <= 0 or 0 < len(props[6]) or len(props[2]) > 0 or not (props[3] is None) or self.clearance:
            # logo.Mlog.logger.error(
            #     f"没有敌人{len(props[0])}= {len(props[6])}={len(props[2])}={props[3]}={self.clearance}")
            y = 0
            self.cut_times.add_enemy_encounter(0)
        else:
            self.cut_times.add_enemy_encounter(0)
            y = 1
            # 加入敌人
            # logo.Mlog.logger.error(
            #     f"有敌人{len(props[0])}= {len(props[6])}={len(props[2])}={props[3]}={self.clearance}")
        if y == 1:
            # 当前是敌人状态
            self.sm.transition_to("ft")
        else:
            self.player.key_pro.clear_key()
            # 狮子头的前一个房间 判定条件是只要门柱大于5，并且没有到达过狮子头房间，就在狮子头前一个房间准备去狮子头房间
            # logo.Mlog.logger.error(f" {len(self.exports)}={self.leo_ok}={self.leo_pre_room}")
            if len(props[1]) > 0:
                # logo.Mlog.logger.error(f"捡材料 {len(props[1])}")
                self.sm.transition_to("sf")
                return
            elif self.leo_pre_room and not self.leo_ok:
                # logo.Mlog.logger.debug(f"self.leo_pre_room 条件 进入狮子头前一个房间状态")
                self.sm.transition_to("szt_pre")
            elif len(props[2]) > 0 or len(props[6]) > 0:
                self.sm.transition_to("fd")
                return
            else:
                # logo.Mlog.logger.error(f"icos= {len(self.ico)}")
                for ic in self.ico:
                    # if ic.name == "通关":
                    #     self.is_through = True
                    if ic.name == "age_tips" or ic.name == "start_game":
                        self.sm.transition_to("eg")
                        logo.Mlog.logger.error(f" 踢下线了")
                        return
                    if ic.name == "再次挑战" or ic.name == "返回城镇":
                        self.sm.transition_to("ov")
                        # self.agan_fail_times += 1
                        # if self.agan_fail_times >= 100:
                        #     self.agan_fail_times = 0
                        #     logo.Mlog.logger.error(f" 点击 再次挑战 超出了次数了")
                        #     # self.back_town()
                        #     self.check_pl()
                        #     return
                        # self.check_pl()

            # self.role.set_times(self.times.count_01_pairs())

    def is_leo_pre_room(self):
        if not self.end_guidepost is None and len(self.exports) > 1:
            filtered_list = [x for x in self.exports if
                             Vector.distance(x.getPot(),
                                             self.end_guidepost.getPot()) <= self.end_guidepost.getWH().y * 3]
            # logo.Mlog.logger.debug(f"距离路标最近的2个门柱={len(filtered_list)}")
            if len(filtered_list) <= 1: return
            v = filtered_list[0].getPot() - filtered_list[1].getPot()
            # logo.Mlog.logger.debug(f"距离路标最近的2个门柱的角度={v.get_angle360()}")
            # str = Vector.determine_vertical_position(self.end_guidepost.getPot(), filtered_list[0].getPot())
            # logo.Mlog.logger.debug(f" 终点路标 距离路标最近的2个门柱的方位={self.first_room}")
            if (350 <= v.get_angle360() and not self.first_room and not self.leo_ok or
                    v.get_angle360() <= 10 and not self.first_room and not self.leo_ok):
                logo.Mlog.logger.debug(f" 下一个房间是狮子头的前一个房间")
                self.leo_condition = True

    def cut_room_reset(self):
        # 先判断当前这个房间是不是已经通关过了的
        logo.Mlog.logger.warn(f"换房间了  self.leo_room={self.leo_pre_room}")
        self.enemy = []
        self.stuff = []
        # 三角形路标
        self.guidepost = []
        self.exports = []
        self.ico = []
        # boss路标,终点引路标志
        self.end_guidepost = None
        # self.leo_pre_room = False
        self.leo_room = False
        self.exports = []


    # 再次挑战 重置一些属性
    def reset_Copy(self):
        self.cut_times.reset()
        self.leo_room = False
        self.leo_pre_room = False
        self.clearance = False
        self.leo_ok = False
        self.player.buff_ok = False
        self.player.is_final_skill = False
        self.player.reset_player()
        self.first_room = True
        # self.leo_condition = False

    def check_pl(self):
        action = taskPro.taskPro.getAction("chooseOther")
        if action.click():
            time.sleep(1)
            # 返回城镇成功，进入切换角色状态
            plz = get_plz()
            time.sleep(0.5)
            logo.Mlog.logger.warn(f"剩余疲劳值={plz}")
            if plz == 0:
                logo.Mlog.logger.warn("没有疲劳值了")
                action = taskPro.taskPro.getAction("backTown2")
                action.click()
                self.back_town()
                self.times.reset()
                return
            # residue_times = math.ceil(plz / 9)
            action = taskPro.taskPro.getAction("fightBegen")
            action.click()

    def back_town(self):
        action = taskPro.taskPro.getAction("backTown")
        if action.click():
            # 返回城镇成功，进入切换角色状态
            logo.Mlog.logger.debug("返回城镇成功")
            self.sm.transition_to("house")
            return
        else:
            logo.Mlog.logger.debug("返回城镇失败")

    def closest_edge(self, point: Vector, rectangle: Rectangle) -> int:
        dist_left = point.x - rectangle.xmin
        dist_right = rectangle.xmax - point.x
        dist_top = rectangle.ymax - point.y
        dist_bottom = point.y - rectangle.ymin
        min_distance = min(dist_left, dist_right, dist_top, dist_bottom)
        # 调试输出
        # print(f"dist_left: {dist_left}, dist_right: {dist_right}, dist_top: {dist_top}, dist_bottom: {dist_bottom}")
        # print(f"min_distance: {min_distance}")
        if min_distance == dist_left:
            # "left"
            return 0
        elif min_distance == dist_right:
            # "right"
            return 1
        elif min_distance == dist_top:
            # "top"
            return 2
        elif min_distance == dist_bottom:
            # "bottom"
            return 3

    # 获取屏幕的尺寸大小
    def get_screens(self):
        screenshot = event.event.take_screenshot()
        # 获取图像的宽度和高度
        height, width, _ = screenshot.shape
        # 计算屏幕的 xmin、xmax、ymin、ymax
        xmin = 0
        xmax = width - 1
        ymin = 0
        ymax = height - 1
        self.rect = Rectangle(xmin, xmax, ymin, ymax)
        # print(f"xmin: {xmin}, xmax: {xmax}, ymin: {ymin}, ymax: {ymax}")

    # def get_yg_pot(self):
    def are_points_on_horizontal_line(self, points: [Vector], tolerance: float):
        if len(points) < 2:
            return False  # 单个点或没有点都认为在同一条线上
        mean_y = sum(point.y for point in points) / len(points)

        for point in points:
            if not (mean_y - tolerance <= point.y <= mean_y + tolerance):
                return False
        return True

    def are_points_on_vertical_line(self, points: [Vector], tolerance: float):
        if len(points) < 2:
            return False  # 单个点或没有点都认为在同一条线上
        mean_x = sum(point.x for point in points) / len(points)
        for point in points:
            if not (mean_x - tolerance <= point.x <= mean_x + tolerance):
                return False
        return True
